extern screen_pixeles

%include "constantes.mac"

%define p_pantalla		 	[ebp - 4]

global negative
section .text

negative:
	push ebp			; creo el marco de la pila
	mov ebp, esp			; creo el marco de la pila
	sub esp, 4			; reservo memoria en la pila

	push ebx			; salvo registros convencion C
	push edi			; salvo registros convencion C
	push esi			; salvo registros convencion C

	mov eax, [screen_pixeles]	; p_pantalla = screen_pixels
	mov p_pantalla, eax		; p_pantalla = screen_pixels

	mov ecx, ancho_pantalla_bytes	; inicializo indice del ciclo de filas
	shr ecx, 3			; inicializo indice del ciclo de filas
	sub ecx,100			; inicializo indice del ciclo de filas

	mov ebx, 0			; contador filas totales

cicloPrimerLinea:

	mov eax, p_pantalla		; xmm0 = linea de 5 pixeles a modificar
	movups xmm0, [eax]		; xmm0 = linea de 5 pixeles a modificar

	add eax, ancho_pantalla_bytes	; xmm1 = linea de 5 pixeles inferior
	movups xmm1, [eax]		; xmm1 = linea de 5 pixeles inferior

	movups xmm3, xmm0		; guardo referencia a xmm0 (la uso tmb como siguiente linea superior)
	movups xmm4, xmm0		; copia de xmm0 a shiftear
	movups xmm5, xmm0		; copia de xmm0 para obtener pixel no modificado (a procesar en sgte iteracion)

	movups xmm0, xmm1		; C(px) = inf(px)
	addps xmm0, xmm6		; C(px) = inf(px) + sup(px)

obtengo_anterior:

	pslldq xmm4, 3			; shift de xmm0_original a izquierda
	paddb xmm4, xmm5		; completo con el pixel del proceso anterior (si hay, sino xmm5 esta en cero)
	addps xmm0, xmm4		; C(px) = ant(px) + inf(px) + sup(px) 

	jmp obtengo_mascara_pixel	; piso xmm5 con el nuevo pixel
	sigo_ciclo_2:			; piso xmm5 con el nuevo pixel

obtengo_siguiente:

	movups xmm4, xmm3		; xmm4 = xmm0_original
	psrldq xmm4, 3			; shift de xmm0_original a derecha
	addps xmm0, xmm4		; C(px) = inf(px) + ant(px) + sgte(px)

	jmp calculos_en_float_sobre_xmm0
	modifico_pantalla:

	mov esi, p_pantalla		; cambio cada color de pixel original por el calculo
	movups [esi], xmm0		; cambio cada color de pixel original por el calculo

loopeo_sobre_fila:
	mov eax, p_pantalla		; muevo puntero 12 bytes
	add eax, 12			; muevo puntero 12 bytes
	mov p_pantalla, eax		; muevo puntero 12 bytes
	loop cicloPrimerLinea
	

cambio_de_fila:

	inc ebx				; incremento contador de filas
	xor ecx, ecx			; si itere alto_pantalla_bytes/2 termine de recorrer la pantalla
	mov ecx, alto_pantalla_bytes	; si itere alto_pantalla_bytes/2 termine de recorrer la pantalla
	shr ecx, 1			; si itere alto_pantalla_bytes/2 termine de recorrer la pantalla
	cmp ebx, ecx			; si itere alto_pantalla_bytes/2 termine de recorrer la pantalla
	je fin				; si itere alto_pantalla_bytes/2 termine de recorrer la pantalla

	movups xmm6, xmm3		; xmm6 = linea superior a la que modifico

	mov eax, [screen_pixeles]	; p_pantalla = screen_pixels
	mov p_pantalla, eax		; p_pantalla = screen_pixels

	mov eax, ancho_pantalla_bytes	; muevo a la siguiente fila de la pantalla
	mul ebx				; muevo a la siguiente fila de la pantalla
	add p_pantalla, eax		; muevo a la siguiente fila de la pantalla

	mov ecx, ancho_pantalla_bytes	; restauro cantidad iteraciones en la fila
	shr ecx, 3			; restauro cantidad iteraciones en la fila
	sub ecx,100			; restauro cantidad iteraciones en la fila

loopeo_sobre_nueva_fila:

	jmp cicloPrimerLinea		; itero sobre la fila


obtengo_mascara_pixel:
	xor eax, eax			; obtengo mascara del ultimo pixel
	movups xmm5, xmm3		; copia de xmm0 para la mascara del pixel
	mov eax, 0xFFFFFF00
	movd xmm6, eax
	pshufd xmm6, xmm6, 11001111b	; mascara en xmm6
	pand xmm5, xmm6			; obtengo el pixel
	psrldq xmm5, 9			; en xmm5 tengo los 3 bytes del ultimo pixel de la linea antes procesada
jmp sigo_ciclo_2

calculos_en_float_sobre_xmm0:
	; aca tengo q dividir xmm0 por 255, sumar 1, aplicar raiz e inversa (ver q hay una fc) y multiplicar por 255
	;xor eax, eax			
	;mov eax, 0x00000000
	;movd xmm0, eax
	;pshufd xmm0, xmm0, 11001111b	
jmp modifico_pantalla

fin:
	pop esi		; desarmo el stack frame
	pop edi		; desarmo el stack frame
	pop ebx		; desarmo el stack frame
	add esp, 4 	; desarmo el stack frame
	pop ebp		; desarmo el stack frame
	ret
